package com.yunianvh.webrtc_compose_demo

import android.Manifest
import android.os.Bundle
import android.text.TextUtils
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.annotation.NonNull
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.drake.net.NetConfig.app
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.XXPermissions
import com.yunianvh.webrtc_compose_demo.ui.theme.WebRTCComposeDemoTheme
import com.yunianvh.webrtc_compose_demo.util.FLogUtil
import com.yunianvh.webrtc_compose_demo.webrtc.WebRTCUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.webrtc.EglBase
import org.webrtc.RendererCommon
import org.webrtc.SurfaceViewRenderer

/**
 * Created by 玉念聿辉.
 * Use: WebRTC Demo
 * Date: 2023/5/9
 * Time: 11:23
 */
class MainActivity : ComponentActivity() {
    private val permissionArray = arrayOf(
        Manifest.permission.RECORD_AUDIO,
        Manifest.permission.CAMERA,
        Manifest.permission.WRITE_EXTERNAL_STORAGE,
        Manifest.permission.READ_EXTERNAL_STORAGE
    )
    private var mEglBase: EglBase = EglBase.create()
    private var webRtcUtil1: WebRTCUtil? = null
    private var pushUrl =
        mutableStateOf("https://192.168.1.172/index/api/webrtc?app=live&stream=test&type=push")
    private var surfaceViewRenderer1: SurfaceViewRenderer? = null

    /**
     * 开始推流
     */
    private fun doPush() {
        if (TextUtils.isEmpty(pushUrl.value)) {
            Toast.makeText(this@MainActivity, "推流地址为空!", Toast.LENGTH_SHORT).show()
            return
        }
        if (webRtcUtil1 != null) {
            webRtcUtil1!!.destroy()
        }
        webRtcUtil1 = WebRTCUtil(this@MainActivity)
        webRtcUtil1!!.create(
            mEglBase,
            surfaceViewRenderer1,
            isPublish = true,
            isShowCamera = true,
            playUrl = pushUrl.value,
            callBack = object : WebRTCUtil.WebRtcCallBack {
                override fun onSuccess() {}
                override fun onFail() {}
            })
    }

    private var webRtcUtil2: WebRTCUtil? = null
    private var playUrl =
        mutableStateOf("https://192.168.1.172/index/api/webrtc?app=live&stream=test&type=play")
    private var surfaceViewRenderer2: SurfaceViewRenderer? = null
    /**
     * 开始播放
     */
    private fun doPlay() {
        if (webRtcUtil2 != null) {
            webRtcUtil2!!.destroy()
        }
        webRtcUtil2 = WebRTCUtil(this@MainActivity)
        webRtcUtil2!!.create(
            mEglBase,
            surfaceViewRenderer2,
            isPublish = false,
            isShowCamera = true,
            playUrl = playUrl.value,
            callBack = object : WebRTCUtil.WebRtcCallBack {
                override fun onSuccess() {}
                override fun onFail() {}
            })
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        FLogUtil.init(this, true)//初始化日志工具
        app = this //初始化net
        getPermissions()//检测权限
        webRtcUtil1 = WebRTCUtil(this@MainActivity)
        webRtcUtil2 = WebRTCUtil(this@MainActivity)

        setContent {
            WebRTCComposeDemoTheme {
                Column(modifier = Modifier.fillMaxWidth()) {
                    //推流地址输入框以及开始推流按钮
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Box(
                            modifier = Modifier.weight(1f)
                        ) {
                            TextField(
                                value = pushUrl.value,
                                onValueChange = {
                                    pushUrl.value = it
                                },
                                textStyle = TextStyle(
                                    color = Color(0xFF000000),
                                    fontSize = 14.sp
                                ), colors = TextFieldDefaults.textFieldColors(
                                    backgroundColor = Color(0x00FFFFFF),
                                    disabledIndicatorColor = Color.Transparent,
                                    errorIndicatorColor = Color.Transparent,
                                    focusedIndicatorColor = Color.Transparent,
                                    unfocusedIndicatorColor = Color.Transparent
                                ),
                                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
                                placeholder = {
                                    Text(
                                        text = "请输入推流地址",
                                        style = TextStyle(
                                            fontSize = 14.sp,
                                            color = Color(0xffc0c4cc)
                                        )
                                    )
                                }
                            )
                        }

                        Box(
                            modifier = Modifier
                                .clickable {
                                    doPush()//开始推流
                                }
                                .width(80.dp)
                                .background(
                                    Color.White,
                                    RoundedCornerShape(5.dp)
                                )
                                .border(
                                    1.dp,
                                    Color(0xFF000000),
                                    shape = RoundedCornerShape(5.dp)
                                )
                                .padding(5.dp),
                            contentAlignment = Alignment.Center
                        ) {
                            Text(text = "推流")
                        }
                    }

                    //推流预览部分
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(300.dp)
                    ) {
                        surfaceViewRenderer1 = mSurfaceViewRenderer(mEglBase, webRtcUtil1!!)
                        AndroidView({ surfaceViewRenderer1!! }) { videoView ->
                            CoroutineScope(Dispatchers.Main).launch {
                                //根据视频大小缩放surfaceViewRenderer控件
                                var screenSize = "480-640"
                                var screenSizeD = 720 / 1280.0
                                val screenSizeS: Array<String> =
                                    screenSize.split("-").toTypedArray()
                                screenSizeD =
                                    screenSizeS[0].toInt() / (screenSizeS[1].toInt() * 1.0)
                                var finalScreenSizeD = screenSizeD
                                var vto = videoView.viewTreeObserver
                                vto.addOnPreDrawListener {
                                    var width: Int = videoView.measuredWidth
                                    var height: Int = (finalScreenSizeD * width).toInt()
                                    //获取到宽度和高度后，可用于计算
                                    var layoutParams = videoView.layoutParams
                                    layoutParams.height = height
                                    videoView.layoutParams = layoutParams
                                    true
                                }
                            }
                        }
                    }

                    //拉流地址
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Box(
                            modifier = Modifier.weight(1f)
                        ) {
                            Text(text = playUrl.value)
                        }
                        Box(
                            modifier = Modifier
                                .clickable {
                                    doPlay()//开始播放
                                }
                                .width(80.dp)
                                .background(
                                    Color.White,
                                    RoundedCornerShape(5.dp)
                                )
                                .border(
                                    1.dp,
                                    Color(0xFF000000),
                                    shape = RoundedCornerShape(5.dp)
                                )
                                .padding(5.dp),
                            contentAlignment = Alignment.Center
                        ) {
                            Text(text = "拉流")
                        }
                    }
                    //拉流部分
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(300.dp)
                    ) {
                        surfaceViewRenderer2 = mSurfaceViewRenderer2(mEglBase, webRtcUtil2!!)
                        AndroidView({ surfaceViewRenderer2!! }) { videoView ->
                            CoroutineScope(Dispatchers.Main).launch {
                                //根据视频大小缩放surfaceViewRenderer控件
                                var screenSize = "480-640"
                                var screenSizeD = 720 / 1280.0
                                val screenSizeS: Array<String> =
                                    screenSize.split("-").toTypedArray()
                                screenSizeD =
                                    screenSizeS[0].toInt() / (screenSizeS[1].toInt() * 1.0)
                                var finalScreenSizeD = screenSizeD
                                var vto = videoView.viewTreeObserver
                                vto.addOnPreDrawListener {
                                    var width: Int = videoView.measuredWidth
                                    var height: Int = (finalScreenSizeD * width).toInt()
                                    //获取到宽度和高度后，可用于计算
                                    var layoutParams = videoView.layoutParams
                                    layoutParams.height = height
                                    videoView.layoutParams = layoutParams
                                    true
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 申请权限
     */
    private fun getPermissions() {
        XXPermissions.with(this@MainActivity)
            .permission(permissionArray)
            .request(object : OnPermissionCallback {
                override fun onGranted(@NonNull permissions: List<String>, allGranted: Boolean) {
                    if (!allGranted) {
                        Toast.makeText(this@MainActivity, "请打开必要权限，以免影响正常使用！", Toast.LENGTH_LONG)
                            .show()
                        return
                    }
                }

                override fun onDenied(@NonNull permissions: List<String>, doNotAskAgain: Boolean) {
                    if (doNotAskAgain) {
                        Toast.makeText(this@MainActivity, "被永久拒绝授权，请手动授予权限", Toast.LENGTH_LONG)
                            .show()
                        // 如果是被永久拒绝就跳转到应用权限系统设置页面
                        XXPermissions.startPermissionActivity(this@MainActivity, permissions)
                    } else {
                        Toast.makeText(this@MainActivity, "获取权限失败", Toast.LENGTH_LONG).show()
                    }
                }
            })
    }
}

/**
 * 由于Compose还没出SurfaceViewRenderer的替代品，这里我们还是用xlm来实现
 */
@Composable
fun mSurfaceViewRenderer(mEglBase: EglBase, webRtcUtil1: WebRTCUtil): SurfaceViewRenderer {
    val context = LocalContext.current
    val surfaceViewRenderer = remember {
        SurfaceViewRenderer(context).apply {
            id = R.id.surface_view
        }
    }
    //Makes MapView follow the lifecycle of this composable
    val lifecycleObserver = rememberMapLifecycleObserver(surfaceViewRenderer, mEglBase, webRtcUtil1)
    val lifecycle = LocalLifecycleOwner.current.lifecycle
    DisposableEffect(lifecycle) {
        lifecycle.addObserver(lifecycleObserver)
        onDispose {
            lifecycle.removeObserver(lifecycleObserver)
        }
    }
    return surfaceViewRenderer
}
@Composable
fun mSurfaceViewRenderer2(mEglBase: EglBase, webRtcUtil2: WebRTCUtil): SurfaceViewRenderer {
    val context = LocalContext.current
    val surfaceViewRenderer = remember {
        SurfaceViewRenderer(context).apply {
            id = R.id.surface_view_2
        }
    }
    //Makes MapView follow the lifecycle of this composable
    val lifecycleObserver = rememberMapLifecycleObserver(surfaceViewRenderer, mEglBase, webRtcUtil2)
    val lifecycle = LocalLifecycleOwner.current.lifecycle
    DisposableEffect(lifecycle) {
        lifecycle.addObserver(lifecycleObserver)
        onDispose {
            lifecycle.removeObserver(lifecycleObserver)
        }
    }
    return surfaceViewRenderer
}
@Composable
fun rememberMapLifecycleObserver(
    surfaceViewRenderer: SurfaceViewRenderer,
    mEglBase: EglBase, webRtcUtil: WebRTCUtil
): LifecycleEventObserver =
    remember(surfaceViewRenderer) {
        LifecycleEventObserver { _, event ->
            when (event) {
                Lifecycle.Event.ON_CREATE -> {
                    surfaceViewRenderer.init(mEglBase.eglBaseContext, null)
                    surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL)
                    surfaceViewRenderer.setEnableHardwareScaler(true)
                    surfaceViewRenderer.setZOrderMediaOverlay(true)
                }
                Lifecycle.Event.ON_START -> {
                }
                Lifecycle.Event.ON_RESUME -> {
                }
                Lifecycle.Event.ON_PAUSE -> {
                }
                Lifecycle.Event.ON_STOP -> {
                }
                Lifecycle.Event.ON_DESTROY -> {
                    webRtcUtil.destroy()
                }
                else -> throw IllegalStateException()
            }
        }
    }